#include "logger.h"

#include <thread>
#include <time.h>
#include <iostream>

// 设置日志级别
void Logger::SetLogLevel(LogLevel logLevel)
{
    m_logLevel = logLevel;
}

// 写日志，把日志信息写入 LockQueue 缓冲区
void Logger::Log(std::string msg)
{
    m_lckQue.Push(msg);
}

// 获取日志单例
Logger& Logger::GetInstance()
{
    static Logger logger;
    return logger;
}

Logger::Logger()
{
    // 启动专门的写日志线程
    std::thread writeLogTask([&](){
        for(;;)
        {
            // 获取当前的日期，取日志信息，写入相应的日志文件中 a+
            // 获取1970到现在的秒数
            time_t now = time(nullptr);
            tm* nowtm = localtime(&now);

            char file_name[128] = {0};  // 文件名
            sprintf(file_name, "%04d-%02d-%02d-log.txt", nowtm->tm_year + 1900,
                                                   nowtm->tm_mon + 1,
                                                   nowtm->tm_mday);

            FILE* pf = fopen(file_name, "a+");
            if(pf == nullptr)
            {
                std::cout << "logger file : " << file_name << " open error!" << std::endl;
                exit(EXIT_FAILURE);
            }

            std::string msg = m_lckQue.Pop();  // 如果队列里没有消息，会阻塞在这里，Pop不会返回

            // 加时间戳
            char time_buf[128] = {0};
            sprintf(time_buf, "%02d:%02d:%02d => [%s] ", nowtm->tm_hour, 
                                                         nowtm->tm_min, 
                                                         nowtm->tm_sec, 
                                                         (m_logLevel == INFO ? "INFO" : "ERROR"));
            msg.insert(0, time_buf);
            msg.append("\n");

            // 文件追加
            fputs(msg.c_str(), pf);

            // 文件关闭
            fclose(pf);
        }
    });

    // 设置分离线程，守护线程
    writeLogTask.detach();
}